package com.zlm.custom.proxy;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author zlm
 * @date 2025/4/22
 */
public class MyInterfaceFactory {

    private static final AtomicInteger count = new AtomicInteger(0);

    public static File createJavaFile(String className,MyHandler myHandler) throws IOException {

        String context = "package com.zlm.custom.proxy;\n" +
                "\n" +
                "public class "+className+" implements MyInterface{\n" +
                "    MyInterface myInterface;\n" +
                "    @Override\n" +
                "    public void func1() {\n" +
                "        "+myHandler.functionBody("func1")+"\n" +
                "    }\n" +
                "\n" +
                "    @Override\n" +
                "    public void func2() {\n" +
                "        "+myHandler.functionBody("func2")+"\n" +
                "    }\n" +
                "\n" +
                "    @Override\n" +
                "    public void func3() {\n" +
                "        "+myHandler.functionBody("func3")+"\n" +
                "    }\n" +
                "}\n";
        File file = new File(className+".java");
        Files.write(file.toPath(),context.getBytes(StandardCharsets.UTF_8));
        return file;
    }

    private static String getClassName() {
        return "MyInterface$proxy" + count.incrementAndGet();
    }

    private static MyInterface newInstance(String className,MyHandler myHandler) throws Exception {
        Class<?> aClass = MyInterfaceFactory.class.getClassLoader().loadClass(className);
        Constructor<?> constructor = aClass.getConstructor();
        MyInterface proxy = (MyInterface) constructor.newInstance();
        myHandler.setProxy(proxy);
        return proxy;
    }

    public static MyInterface createProxyInstance(MyHandler myHandler) throws Exception {
        String className = getClassName();
        File javaFile = createJavaFile(className, myHandler);
        Compiler.compile(javaFile);
        return newInstance("com.zlm.custom.proxy." + className, myHandler);
    }

}
